#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

// 验证整个地址空间内分区
// int g_val_1;        // 未初始化全局变量
// int g_val_2 = 10;   // 已初始化全局变量
// int main(int argc, char* argv[], char* env[])
// {
//     printf("code addr: %p\n", main);                         // 正文代码段

//     const char* str = "hello world";
//     printf("read only string addr: %p\n", str);             //只读数据区

//     printf("init global value addr: %p\n", &g_val_2);       // 已初始化全局变量区
//     printf("uninit global value addr: %p\n", &g_val_1);     // 未初始化全局变量区

//     char* mem = (char*)malloc(100);
//     printf("heap addr: %p\n", mem);                         // 堆区

//     printf("stack addr: %p\n", &str);                       // 栈区
//     printf("命令行参数：%p\n", argv[0]);                     // 命令行参数
//     printf("环境变量env：%p\n", env[0]);                     // 环境变量
//     return 0;
// }

// 验证堆、栈、命令行参数、环境变量空间内地址变量分布
// int main(int argc, char* argv[], char* env[])
// {
//     printf("-----------------------------------\n");
//     printf("验证堆：\n");
//     char* mem1 = (char*)malloc(100);
//     char* mem2 = (char*)malloc(100);
//     char* mem3 = (char*)malloc(100);
//     char* mem4 = (char*)malloc(100);
//     printf("heap addr1: %p\n", mem1);
//     printf("heap addr2: %p\n", mem2);
//     printf("heap addr3: %p\n", mem3);
//     printf("heap addr4: %p\n", mem4);

//     printf("-----------------------------------\n");
//     printf("验证栈：\n");
//     int a = 10;
//     int b = 10;
//     int c = 10;
//     int d = 10;
//     printf("stack addr_a: %p\n", &a);
//     printf("stack addr_b: %p\n", &b);
//     printf("stack addr_c: %p\n", &c);
//     printf("stack addr_d: %p\n", &d);

//     printf("-----------------------------------\n");
//     printf("验证命令行参数：\n");
//     for (size_t i = 0; argv[i]; i++)
//     {
//         printf("argv[%d]: %p\n", i, argv[i]);
//     }

//     printf("-----------------------------------\n");
//     printf("验证环境变量：\n");
//     for (size_t i = 0; env[i]; i++)
//     {
//         printf("env[%d]: %p\n", i, env[i]);
//     }

//     return 0;
// }

// 引入虚拟地址
int g_val = 100;
int main()
{
    int id = fork();
    if (id == 0)
    {
        // child
        while (1)
        {
            printf("pid: %d, ppid: %d, g_val: %d, &g_val: %p\n", getpid(), getppid(), g_val, &g_val);
            g_val--;
            sleep(1);
        }
    }
    // parent
    while (1)
    {
        printf("pid: %d, ppid: %d, g_val: %d, &g_val: %p\n", getpid(), getppid(), g_val, &g_val);
        sleep(1);
    }

    return 0;
}

struct mm_struct
{
    // 代码区
    unsigned long code_start;   // 起始
    unsigned long code_end;     // 末尾

    // 只读区
    unsigned long readonly_start;   // 起始
    unsigned long readonly_end;     // 末尾

    // 初始化数据区
    unsigned long init_start;   // 起始
    unsigned long init_end;     // 末尾

    // 未初始化数据区
    unsigned long uninit_start;   // 起始
    unsigned long uninit_end;     // 末尾

    // 堆区
    unsigned long heap_start;   // 起始
    unsigned long heap_end;     // 末尾

    // 栈区
    unsigned long stack_start;   // 起始
    unsigned long stack_end;     // 末尾

    // 。。。。
};